package com.scalar.chiptrack.adaptor.mitsui;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.AssemblyLot;
import com.scalar.chiptrack.adaptor.ShippedLot;
import com.scalar.chiptrack.adaptor.dao.AdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;
import com.scalar.chiptrack.adaptor.dao.AssemblyAdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.ShippedLotDAO;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.chiptrack.db.DBTransaction;
import com.scalar.ScalarException;

import java.util.HashMap;
import java.util.ArrayList;
import java.util.Iterator;

import java.io.File;

import jxl.Workbook;
import jxl.Sheet;
import jxl.Cell;
import jxl.CellType;

/**
 * User: ChandraSekhar
 * Date: Sep 3, 2007
 * Time: 1:56:03 PM
 */
public class MitsuiDataParser extends JobHandler implements AdaptorConstants
{
    HashMap m_assemblyDataMap       = new HashMap();
    HashMap m_shipDataMap           = new HashMap();

    private Logger m_parserLogger   = null;
    private String m_dataOutputDir  = null;
    DBTransaction dbTransaction     = null;

    public MitsuiDataParser() throws Exception
    {
        try
        {
            m_dataOutputDir = AdaptorUtils.getDataOutputDir( VENDOR_NAME_MITSUI, WIP_TYPE_ASSEMBLY );
            AdaptorUtils.makeAllAdaptorDirs( m_dataOutputDir );
            m_parserLogger = AdaptorUtils.getDataParserLogger( m_dataOutputDir, VENDOR_NAME_MITSUI );
            AssemblyAdaptorDAO.setLogger( m_parserLogger);
            ShippedLotDAO.setLogger( m_parserLogger );
            AdaptorUtils.setLogger(m_parserLogger);
        }
        catch (ScalarException e)
        {
            log( "ERROR!! ERROR!! ERROR!! Exception while loading MITSUI output directory details from database, Exception: " + e );
            throw e;
        }
    }

    public static void main(String args[]) throws Exception
    {
        new MitsuiDataParser().execute();
    }

    public void execute() throws Exception
    {
        AdaptorUtils.printHeader(VENDOR_NAME_MITSUI, CONSTANT_PARSER );

        File doneDestDir = new File(m_dataOutputDir + "/done");

        File wipDataoutDir = new File(m_dataOutputDir);

        File[] fileList = wipDataoutDir.listFiles();

        if ((fileList == null) || (fileList.length <= 3))
        {
            log("No file found in directory: " + wipDataoutDir);
            throw new ScalarException("No file found in directory: " + wipDataoutDir + "----\n\n");
        }

        ArrayList successFileList   = new ArrayList();
        boolean success             = false;

        //PARSING STARTS FROM HERE
        for (int i = 0; i < fileList.length; i++)
        {
            if (fileList[i].isDirectory() == true)
            {
                continue;
            }

            if ( (fileList[i].getName() != null) && fileList[i].getName().trim().startsWith( MitsuiAdaptor.FILE_NAME_WIP ) )
            {
                try
                {
                    ArrayList m_wipStatusList = parseWipInfosheet( fileList[i].getAbsolutePath() );

                    if ( m_wipStatusList != null && m_wipStatusList.size() > 0)
                    {
                        getWipDetails( m_wipStatusList );
                    }
                    successFileList.add( fileList[i] );
                }
                catch( Exception e )
                {
                    success = false;
                    log("Exception while parsing file: " + fileList[i].getAbsolutePath() + "\nException: " + e);
                    e.printStackTrace();
                    throw e;
                }
            }
        }

        /*Updating the Assembly Lot Information*/
        try
        {
            // Step 3
            // Save Assembly Information
            if( m_assemblyDataMap.isEmpty() == false )
            {
                log(" Updating Assembly Lot Information");
                AssemblyAdaptorDAO.saveAssemblyLot( dbTransaction, m_assemblyDataMap.values().iterator(), WIP_TYPE_ASSEMBLY, VENDOR_NAME_MITSUI );
            }
            else
            {
                AssemblyAdaptorDAO.closeAssemblyLot( dbTransaction, WIP_TYPE_ASSEMBLY, VENDOR_NAME_MITSUI );
            }
            m_assemblyDataMap.clear();
            m_assemblyDataMap = null;
            success = true;
        }
        catch (ScalarException se)
        {
            success = false;
            se.printStackTrace();
            log("ERROR!! ERROR!! ERROR!! Could not update Assembly Lot information into database: " + se);
            throw se;
        }

        try
        {
            // Step 2
            // Save Test Shipping Information
            if( m_shipDataMap.isEmpty() == false )
            {
                log(" Updating Test Shipping Lot Information");
                ShippedLotDAO.saveShippedLot( dbTransaction, m_shipDataMap.values().iterator()  );
            }
            m_shipDataMap.clear();
            m_shipDataMap = null;
            success = true;
        }
        catch (ScalarException se)
        {
            success = false;
            se.printStackTrace();
            log("ERROR!! ERROR!! ERROR!! Could not update Test Shiiping Lot information into database: " + se);
            throw se;
        }
        // TO SEND THE NEW LOTS, NEW TRANSIT LOTS, NO PO LOTS, DISCREPANCY LOTS NOTIFICATIONS TO THE USER
        AdaptorDAO.sendAllNotifications( VENDOR_NAME_MITSUI, true, true, true);

         // To Close the Drop Out Lots
        AdaptorDAO.closeDropOutLots( VENDOR_NAME_MITSUI );

        int adaptor_id = AdaptorRunInfo.getLastRunAdaptorId( MitsuiAdaptor.ADAPTOR_NAME, CONSTANT_ADAPTOR);

        // Update Adaptor_Run_Info table
        try
        {
            if ( success == true )
            {
                AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, MitsuiAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
                System.out.println( "SUCCESSFULLY UPDATED IN THE DATABASE" );
            }
        }
        catch ( ScalarException se )
        {
            success = false; //As filES DATA SAVED , UPDATEING AS SUCCESS
            AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, MitsuiAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
            log( "WARNING!! WARNING!! WARNING!! Could not update Adaptor run information, Exception: " + se );
            throw se;
        }
        // Step 7
        // Move the successful files to 'done' directory
       if (success)
       {
            AdaptorUtils.moveFilesToDone(successFileList, doneDestDir);
       }
    }//end of execute method

    /**
     *
     * @param fileName
     * @return
     * @throws Exception
     */
    private ArrayList parseWipInfosheet(String fileName) throws Exception
    {
        if ( fileName == null )
        {
            throw new ScalarException( "Filename argument is null" );
        }

        MitsuiWipStatus wipStatus   = null;
        ArrayList wipList           = new ArrayList();

        try
        {
            File wipFedFile = new File( fileName );
            if ( wipFedFile.exists() == false )
            {
                throw new ScalarException( fileName + " doesnt exist" );
            }

            log( "\nFound " + fileName );
            log( "Parsing the file for Mitsui Wip Report..." );
            System.out.println( "\nFound " + fileName );
            System.out.println( "Parsing the file for Mitsui Wip Report..." );

            Workbook workbook = Workbook.getWorkbook( wipFedFile );
            Sheet sheet = workbook.getSheet( 0 );

            Cell[] row = null;

            for ( int rowCount = 1; rowCount < sheet.getRows(); rowCount++ )
            {
                row = sheet.getRow( rowCount );

                wipStatus = new MitsuiWipStatus();

                if( row.length > 0 )
                {
                    if ( row[0].getType().equals(CellType.EMPTY) )
                    {
                        wipStatus.setPin( null );
                    }
                    else
                    {
                        wipStatus.setPin( row[0].getContents().trim() );
                    }
                }
                if( row.length > 1)
                {
                    if ( row[1].getType().equals(CellType.EMPTY) )
                    {
                        wipStatus.setPkg( null );
                    }
                    else
                    {
                        wipStatus.setPkg( row[1].getContents().trim() ) ;
                    }
                }
                if( row.length > 2)
                {
                    if ( row[2].getType().equals(CellType.EMPTY) )
                    {
                        wipStatus.setDevice(null );
                    }
                    else
                    {
                        wipStatus.setDevice( row[2].getContents().trim() );
                    }
                }
                if( row.length > 3)
                {
                    if ( row[3].getType().equals(CellType.EMPTY) )
                    {
                        wipStatus.setAssyReleaseNo(null );
                    }
                    else
                    {
                        wipStatus.setAssyReleaseNo( row[3].getContents().trim() );
                    }
                }
                if( row.length > 4)
                {
                    if ( row[4].getType().equals(CellType.EMPTY) )
                    {
                        wipStatus.setWaferLotNo( null );
                    }
                    else
                    {
                        wipStatus.setWaferLotNo( row[4].getContents().trim() );
                    }
                }
                if( row.length > 5)
                {
                    if ( row[5].getType().equals(CellType.EMPTY) )
                    {
                        wipStatus.setDiePartNo( null );
                    }
                    else
                    {
                        wipStatus.setDiePartNo( row[5].getContents().trim() );
                    }
                }
                if ( row.length > 6 )
                {
                   if ( row[6].getType().equals(CellType.EMPTY) )
                    {
                        wipStatus.setVendorLotNo( null );
                    }
                    else
                    {
                        wipStatus.setVendorLotNo( row[6].getContents().trim() );
                    }
                }
                if( row.length > 7 )
                {
                    if ( row[7].getType().equals(CellType.EMPTY) )
                    {
                        wipStatus.setInDate( null );
                    }
                    else
                    {
                        wipStatus.setInDate( row[7].getContents().trim() );
                    }
                }
                if( row.length > 8 )
                {
                    if ( row[8].getType().equals(CellType.EMPTY) )
                    {
                        wipStatus.setInQty( null );
                    }
                    else
                    {
                        wipStatus.setInQty( row[8].getContents().trim() );
                    }
                }
                if ( row.length > 9 )
                {
                    if ( row[9].getType().equals(CellType.EMPTY) )
                    {
                        wipStatus.setStatus( null );
                    }
                    else
                    {
                        wipStatus.setStatus( row[9].getContents().trim() );
                    }
                }
                if( row.length > 10 )
                {
                    if ( row[10].getType().equals(CellType.EMPTY) )
                    {
                        wipStatus.setQty( null );
                    }
                    else
                    {
                        wipStatus.setQty( row[10].getContents().trim() );
                    }
                }
                if( row.length > 11 )
                {
                    if ( row[11].getType().equals(CellType.EMPTY) )
                    {
                        wipStatus.setCommitDate( null );
                    }
                    else
                    {
                        wipStatus.setCommitDate( row[11].getContents().trim() );
                    }
                }
                if( row.length >12 )
                {
                    if ( row[12].getType().equals(CellType.EMPTY) )
                    {
                        wipStatus.setShipDate( null );
                    }
                    else
                    {
                        wipStatus.setShipDate( row[12].getContents().trim() ) ;
                    }
                }

                if ( wipStatus.getDevice() != null  && wipStatus.getDevice().length() > 0 )
                {
                    wipList.add( wipStatus );
                }
            }
        }
        catch ( Exception ex )
        {
            ex.printStackTrace();
            throw ex;
        }

        return wipList;
    }

    public void getWipDetails( ArrayList wipFedList ) throws Exception
    {
        String fabLotNumber     = null;
        String partNumber       = null;
        String lotNumber        = null;
        String releaseNumber    = null;
        String diePartNumber    = null;
        MitsuiWipStatus wipStatus  = null;
        AssemblyLot assemblyLot    = null;
        ShippedLot shippedLot      = null;
        try
        {
           Iterator wipIterator = wipFedList.iterator();

            while ( wipIterator.hasNext() )
            {
                wipStatus = (MitsuiWipStatus) wipIterator.next();

                partNumber = wipStatus.getDevice();
                diePartNumber = wipStatus.getDiePartNo();
                lotNumber = StringUtils.trimLeadingChar(wipStatus.getVendorLotNo() , '0');
                fabLotNumber = wipStatus.getWaferLotNo();
                releaseNumber   = wipStatus.getAssyReleaseNo();

                if ( wipStatus.getShipDate() != null && wipStatus.getShipDate().length() == 8 )
                {
                    log("In Assebly Ship" + lotNumber );

                    shippedLot = (ShippedLot) m_shipDataMap.get( fabLotNumber + lotNumber + partNumber  );

                    if (shippedLot == null)
                    {
                        shippedLot = new ShippedLot( VENDOR_NAME_MITSUI,  WIP_TYPE_ASSEMBLY );
                        m_shipDataMap.put( fabLotNumber + lotNumber + partNumber , shippedLot);
                    }

                    int quantity = 0;
                    if ( shippedLot.getShipQty() != null )
                    {
                        try
                        {
                            quantity = Integer.parseInt( shippedLot.getShipQty() );
                        }
                        catch (NumberFormatException npe) {
                        }
                        try
                        {
                            quantity += Integer.parseInt( wipStatus.getQty() );
                        }
                        catch (NumberFormatException npe) {
                        }
                    }
                    else
                    {
                        try
                        {
                            quantity = Integer.parseInt( wipStatus.getQty() );
                        }
                        catch (NumberFormatException npe) {
                        }
                    }
                    if ( quantity > 0 )
                    {
                        shippedLot.setLotNumber( lotNumber );
                        shippedLot.setPartNumber( partNumber );
                        shippedLot.setShipDate( StringUtils.formatDate(wipStatus.getShipDate(), "yyyyMMdd", "MM/dd/yyyy" ) );
                        shippedLot.setShipQty( quantity+"" );
                        shippedLot.setFabLotNumber( fabLotNumber );
                        shippedLot.setPackageType( wipStatus.getPkg() );
                    }
                }
                else
                {
                    if ( lotNumber != null && lotNumber.length() > 0 )
                    {
                        if ( releaseNumber != null && releaseNumber.length() > 0 )
                        {
                            int releaseCount = AdaptorDAO.getApprovedAssemblyReleaseLot( releaseNumber, partNumber, VENDOR_NAME_MITSUI );

                            if ( releaseCount > 0 )
                            {
                                AdaptorDAO.updateAssemblyReleaseStatus( releaseNumber );
                            }
                        }
                        assemblyLot = (AssemblyLot)m_assemblyDataMap.get( fabLotNumber + lotNumber + partNumber );
                        if( assemblyLot == null )
                        {
                            assemblyLot = new AssemblyLot();
                            m_assemblyDataMap.put( fabLotNumber + lotNumber + partNumber, assemblyLot );
                        }

                        int quantity = 0;
                        if ( assemblyLot.getQtyIn() != null)
                        {
                            try
                            {
                                quantity = Integer.parseInt(assemblyLot.getQtyIn());
                            }
                            catch (NumberFormatException npe)
                            {
                            }
                            try
                            {
                                quantity += Integer.parseInt(wipStatus.getQty());
                            }
                            catch (NumberFormatException npe)
                            {
                            }
                        }
                        else
                        {
                            try
                            {
                                quantity = Integer.parseInt( wipStatus.getQty() );
                            }
                            catch (NumberFormatException npe)
                            {
                            }
                        }

                        if( quantity > 0 )
                        {
                            assemblyLot.setLotNumber( lotNumber );
                            assemblyLot.setDeviceName( partNumber );
                            assemblyLot.setDateIn( StringUtils.formatDate(wipStatus.getInDate(), "yyyyMMdd", "MM/dd/yyyy" ) );
                            assemblyLot.setQtyIn( quantity +"");
                            assemblyLot.setStage( wipStatus.getStatus() );
                            assemblyLot.setVendorName( VENDOR_NAME_MITSUI );
                            assemblyLot.setStatus( LOT_STATUS_RUNNING);
                            assemblyLot.setFabLotNumber( fabLotNumber );
                            if ( wipStatus.getCommitDate() != null && wipStatus.getCommitDate().length() == 8 )
                            {
                                assemblyLot.setExpectedDateOut( StringUtils.formatDate( wipStatus.getCommitDate(), "yyyyMMdd", "MM/dd/yyyy" ) );
                            }
                            assemblyLot.setPackageType( wipStatus.getPkg() );
                            assemblyLot.setVendorLotNumber( releaseNumber );    // Release number Considering as Vendor Lot No
                        }
                    }
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
            log("ERROR!ERROR! While parsing the MITSUI Wip Details" + e);
            System.out.println("ERROR!ERROR! While parsing the MITSUI Wip Details" + e);
            throw e;
        }
    }

    private void log(String message)
    {
        if (message == null) return;

        if (m_parserLogger != null)
        {
            synchronized (m_parserLogger)
            {
                m_parserLogger.logDebug(message + LINE_SEPARATOR);
            }
        }
        else
        {
            System.out.println(message);
        }
    }

    private void printVersionInfo()
    {
        String info = "\n\n+----------- Running Mitsui Wip Data Parser on " + new java.util.Date(System.currentTimeMillis()) + " -------------+\n" +
                "\n+---------------------------------------------------------------+\n" +
                "+                                                                \n" +
                "+                 Mitsui Wip Data Interpreter - Beta             \n" +
                "+                                                                \n" +
                "+    Copy Right (C) 2007 - ScalarSoft Inc., All rights reserved.  \n" +
                "+                                                                \n" +
                "+---------------------------------------------------------------+\n";
        System.out.println(info);
        log(info);
    } //end of printVersionInfo

}
